#let _refer_to_helper(c, number, ..nums) = {
  link(
    c.location(),
    box(
      clip: true,
      outset: 0.11em,
      stroke: (rest: rgb("#ff0000")),
      text(fill: black)[#numbering(
          number,
          ..nums,
        )],
    ),
  )
}

#let _generate_caption(caption: [], supplement, count) = {
  count.step()
  [#supplement #context count.display() #h(0.65em) #caption]
  v(-0.5em)
}

#let _code-counter = counter("code")

#let code(content, caption: none) = {
  let supplement = "代码"
  figure(kind: "code", supplement: supplement)[
    #_generate_caption(caption: caption, supplement, _code-counter)
    #content
  ]
}

#let _fake-code-counter = counter("fake-code")

#let fake-code(caption: none, input: content, output: content, ..steps) = {
  let supplement = "伪代码"
  figure(kind: "fake-code", supplement: supplement)[
    #_generate_caption(caption: caption, supplement, _fake-code-counter)
    #table(
      align: left,
      stroke: none,
      columns: (0.2fr, 1.2fr),
      table.hline(stroke: 1pt),
      [*Algorithm*], [#caption],
      table.hline(stroke: 0.5pt),
      table.cell(rowspan: 2)[*Input:* \ *Output:* ], [#input \ #output],
    )
    #move(dx: 1em, dy: -2em)[
      #{
        let n = 0
        for step in steps.pos() {
          n += 1
          let n-str = str(n) + "."
          box(
            grid(column-gutter: 0.5em, align: left, columns: (0.05fr, 1.5fr))[#text(
                style: "italic",
                size: 10pt,
              )[#n-str]][#step],
          )
        }
      }
    ]
    #move(dy: -2.5em)[
      #line(length: 100%, stroke: 0.5pt)
    ]
    #v(-1.5em)
  ]
}

#let _graph-counter = counter("graph")

#let graph(path: "", caption: none, alt: "", width: 80%, height: none) = {
  let supplement = "图"
  figure(kind: "graph", supplement: supplement)[
    #if height == none {
      image(path, width: width, alt: alt)
    } else {
      image(path, width: width, height: height, alt: alt)
    }
    #v(-1em)
    #_generate_caption(caption: caption, supplement, _graph-counter)
    #v(1.5em)
  ]
}

#let _table-counter = counter("table-maker")

#let table-maker(
  ..children,
  caption: [],
  align: auto,
  column-gutter: auto,
  columns: auto,
  fill: none,
  gutter: auto,
  inset: 0% + 5pt,
  row-gutter: auto,
  rows: auto,
  stroke: 1pt + black,
) = {
  let supplement = "表"
  figure(supplement: "表", kind: table)[
    #_generate_caption(caption: caption, supplement, _table-counter)
    #table(align: align, column-gutter: column-gutter, columns: columns, fill: fill, gutter: gutter, inset: inset, rows: rows, stroke: stroke, ..children)
  ]
}

#let lib-style(content) = {
  set text(font: ("Noto Sans CJK HK"), size: 12pt, lang: "zh", region: "cn")
  set page(
    paper: "a4",
    header: {
      align(right)[#underline[_Compilation Principles_]]
    },

    // margin: (left: 3.18cm, right: 3.18cm, top: 2.54cm, bottom: 2.54cm),
    numbering: "1/1",
  )

  set heading(numbering: "1.")
  set outline(depth: 3, indent: 2em)

  show heading.where(level: 1): set text(size: 16pt)
  show heading.where(level: 2): it => {
    set text(size: 14pt)
    it
    v(0.25em)
  }
  show heading.where(level: 3): set text(size: 12pt)

  set math.equation(numbering: "(1)", number-align: right)

  set figure.caption(position: top)
  show figure.caption: set text(size: 10pt)

  show link: it => {
    text(fill: blue)[#underline(it)]
  }

  // show ref: it => {
  //   let eq = math.equation
  //   let head = heading
  //   let el = it.element
  //   if el.has("supplement") {
  //     el.supplement + h(0.2em)
  //     if el.func() == head {
  //       _refer_to_helper(el, "1.1", ..counter(head).at(el.location()))
  //     } else if el.func() == eq {
  //       _refer_to_helper(el, "1", ..counter(eq).at(el.location()))
  //     } else if el.has("counter") {
  //       _refer_to_helper(el, "1", ..el.counter.at(el.location()))
  //     }
  //     h(0.05em)
  //   } else {
  //     it
  //   }
  // }

  show cite: it => box(
    it,
    clip: true,
    // outset: 1em,
    inset: 0.01em,
    // baseline: -1em,
    stroke: (rest: rgb("#00bbbf")),
  )


  show raw.where(block: true): set text(size: 10pt, lang: "en")
  show raw.where(block: true): set par(spacing: 70% * 10pt)
  set par(first-line-indent: (all: true, amount: 2em))
  set raw(tab-size: 4)
  show raw.where(block: true): it => box(stroke: (right: 0.5pt))[
    #let counter = 0
    #for codes in it.lines {
      if counter == 0 {
        line(start: (5%, 0pt), end: (100%, 0pt), stroke: 0.5pt)
      }
      counter += 1
      let num = str(codes.number) + "."
      grid(align: left, columns: (0.05fr, 1fr))[#text(size: 8pt, style: "italic")[#num]][#codes.body]
    }
    #line(start: (5%, 0pt), end: (100%, 0pt), stroke: 0.5pt)
  ]

  show raw.where(block: false): it => {
    // h(0.5em)
    box(fill: rgb("#d8d8d8"), outset: 2.5pt, radius: 2pt, clip: true)[
      #it
    ]
  }

  content
}

#let make-title(title: [], name: [], id: 114514) = {
  align(center)[#text(size: 20pt, stroke: 0.2pt)[#title]]

  align(center)[#name (#id)]
  linebreak()
}

#let make-abstract(content, ..keywords) = {
  set text(size: 10pt)

  [#text(stroke: 0.4pt)[摘要：]#content]
  v(1pt)
  {
    [#text(stroke: 0.4pt)[关键词#h(1em)]]
    for word in keywords.pos() {
      text[#word#h(0.5em)]
    }
  }
}

#let make-bibliography(source: "", style: "ieee") = {
  set text(font: "Times New Roman", size: 10pt, lang: "en")
  bibliography(
    source,
    style: style,
    title: text(font: ("Times New Roman", "Heiti SC"), size: 14pt, lang: "zh", region: "cn")[参考文献],
  )
}

#let appendix(body) = {
  set heading(numbering: "1.", supplement: [Appendix], depth: 1)
  counter(heading).update(0)
  body
}

#let AppendixHeading = heading(numbering: "A")[#text("附录", size: 14pt, weight: "bold")]

#let appendix-show(content) = {
  show: appendix
  show raw: set text(size: 8pt)
  // pagebreak()
  content
}
